package net.jwtools.tmt.domain;

import java.io.Serializable;
import java.util.Date;

/**
 * This is an object that contains data related to the VISIT table. Do not
 * modify this class because it will be overwritten if the configuration file
 * related to this class is modified.
 * 
 * @hibernate.class table="VISIT"
 */

public abstract class BaseVisit implements IVisit, Serializable {

	public static String REF = "Visit";
	public static String PROP_STATUS = "status";
	public static String PROP_CHECKOUT_DATE = "checkoutDate";
	public static String PROP_NOT_HOME_NUMBER = "notHomeNumber";
	public static String PROP_TYPE = "type";
	public static String PROP_ID = "id";
	public static String PROP_TERRITORY = "territory";
	public static String PROP_CHECKOUT_BY = "checkoutBy";
	public static String PROP_CHECKIN_DATE = "checkinDate";

	// constructors
	public BaseVisit() {
		initialize();
	}

	/**
	 * Constructor for primary key
	 */
	public BaseVisit(java.lang.Long id) {
		this.setId(id);
		initialize();
	}

	/**
	 * Constructor for required fields
	 */
	public BaseVisit(java.lang.Long id,
			net.jwtools.tmt.domain.Territory territory, VisitType type,
			java.util.Date checkoutDate) {

		this.setId(id);
		this.setTerritory(territory);
		this.setType(type);
		this.setCheckoutDate(checkoutDate);
		initialize();
	}

	protected void initialize() {
		setStatus(Status.ACTIVE);
	}

	private int hashCode = Integer.MIN_VALUE;

	// primary key
	private java.lang.Long id;

	// fields
	private VisitType type;
	private java.util.Date checkoutDate;
	private java.util.Date checkinDate;
	private java.util.Date readyDate;
	private java.lang.Integer notHomeNumber;
	private IVisit belongsTo;
	private net.jwtools.tmt.domain.Status status;

	// many to one
	private net.jwtools.tmt.domain.Territory territory;
	private net.jwtools.tmt.domain.Person checkoutBy;

	/**
	 * Return the unique identifier of this class
	 * 
	 * @hibernate.id generator-class="increment" column="ID"
	 */
	public java.lang.Long getId() {
		return id;
	}

	/**
	 * Set the unique identifier of this class
	 * 
	 * @param id
	 *            the new ID
	 */
	public void setId(java.lang.Long id) {
		this.id = id;
		this.hashCode = Integer.MIN_VALUE;
	}

	/**
	 * Return the value associated with the column: VISIT_TYPE
	 */
	public VisitType getType() {
		return type;
	}

	/**
	 * Set the value related to the column: VISIT_TYPE
	 * 
	 * @param type
	 *            the VISIT_TYPE value
	 */
	public void setType(VisitType type) {
		this.type = type;
	}

	/**
	 * Return the value associated with the column: CHECKOUTDATE
	 */
	public java.util.Date getCheckoutDate() {
		return checkoutDate;
	}

	/**
	 * Set the value related to the column: CHECKOUTDATE
	 * 
	 * @param checkoutDate
	 *            the CHECKOUTDATE value
	 */
	public void setCheckoutDate(java.util.Date checkoutDate) {
		this.checkoutDate = checkoutDate;
	}

	/**
	 * Return the value associated with the column: CHECKINDATE
	 */
	public java.util.Date getCheckinDate() {
		return checkinDate;
	}

	/**
	 * Set the value related to the column: CHECKINDATE
	 * 
	 * @param checkinDate
	 *            the CHECKINDATE value
	 */
	public void setCheckinDate(java.util.Date checkinDate) {
		this.checkinDate = checkinDate;
	}

	/**
	 * Return the value associated with the column: NOTHOME
	 */
	public java.lang.Integer getNotHomeNumber() {
		return notHomeNumber;
	}

	/**
	 * Set the value related to the column: NOTHOME
	 * 
	 * @param notHomeNumber
	 *            the NOTHOME value
	 */
	public void setNotHomeNumber(java.lang.Integer notHomeNumber) {
		this.notHomeNumber = notHomeNumber;
	}

	/**
	 * Return the value associated with the column: status
	 */
	public net.jwtools.tmt.domain.Status getStatus() {
		return status;
	}

	/**
	 * Set the value related to the column: status
	 * 
	 * @param status
	 *            the status value
	 */
	public void setStatus(net.jwtools.tmt.domain.Status status) {
		this.status = status;
	}

	/**
	 * Return the value associated with the column: TERRITORY_ID
	 */
	public net.jwtools.tmt.domain.Territory getTerritory() {
		return territory;
	}

	/**
	 * Set the value related to the column: TERRITORY_ID
	 * 
	 * @param territory
	 *            the TERRITORY_ID value
	 */
	public void setTerritory(net.jwtools.tmt.domain.Territory territory) {
		this.territory = territory;
	}

	/**
	 * Return the value associated with the column: CHECKOUTBY_ID
	 */
	public net.jwtools.tmt.domain.Person getCheckoutBy() {
		return checkoutBy;
	}

	/**
	 * Set the value related to the column: CHECKOUTBY_ID
	 * 
	 * @param checkoutBy
	 *            the CHECKOUTBY_ID value
	 */
	public void setCheckoutBy(net.jwtools.tmt.domain.Person checkoutBy) {
		this.checkoutBy = checkoutBy;
	}

	public boolean equals(Object obj) {
		if (null == obj)
			return false;
		if (!(obj instanceof net.jwtools.tmt.domain.IVisit))
			return false;
		else {
			net.jwtools.tmt.domain.IVisit visit = (net.jwtools.tmt.domain.IVisit) obj;
			if (null == this.getId() || null == visit.getId())
				return false;
			else
				return (this.getId().equals(visit.getId()));
		}
	}

	public int hashCode() {
		if (Integer.MIN_VALUE == this.hashCode) {
			if (null == this.getId())
				return super.hashCode();
			else {
				String hashStr = this.getClass().getName() + ":"
						+ this.getId().hashCode();
				this.hashCode = hashStr.hashCode();
			}
		}
		return this.hashCode;
	}

	public String toString() {
		return getId() + "=" + getType() + " " + getTerritory().getName();
	}

	static final long ONE_HOUR = 60 * 60 * 1000L;

	public long daysBetween(Date d1, Date d2) {
		return ((d2.getTime() - d1.getTime() + ONE_HOUR) / (ONE_HOUR * 24));
	}

	public Long getDaysCheckedout() {
		Long daysCheckedout = null;
		if (getCheckinDate() != null) {
			daysCheckedout = daysBetween(getCheckoutDate(), getCheckinDate());
		} else {
			daysCheckedout = daysBetween(getCheckoutDate(), new Date());
			;
		}
		return daysCheckedout;
	}

	public Long getTotalDaysCheckedout() {
		Long daysCheckedout = null;
		if (this instanceof ReVisit) {
			if (getCheckinDate() != null) {
				daysCheckedout = daysBetween(
						getCheckinDate(),getBelongsTo().getCheckoutDate());
			} else {
				daysCheckedout = daysBetween(
						new Date(),getBelongsTo().getCheckoutDate());
			}
		} else {
			if (getReadyDate() != null) {
				daysCheckedout = daysBetween(
						getCheckinDate(),getReadyDate());
			} else if (getCheckinDate() != null) {
				daysCheckedout = daysBetween(
						getCheckinDate(),getCheckoutDate());
			} else {
				daysCheckedout = daysBetween(
						new Date(),getCheckoutDate());
			}
		}
		return daysCheckedout;
	}

	@Override
	public IVisit getBelongsTo() {
		return belongsTo;
	}

	@Override
	public Date getReadyDate() {
		return readyDate;
	}

	@Override
	public void setBelongsTo(IVisit belongsTo) {
		this.belongsTo = belongsTo;
	}

	@Override
	public void setReadyDate(Date readyDate) {
		this.readyDate = readyDate;
	}
	
	public Date getEndDate() {
		if (getReadyDate()!=null) return getReadyDate();
		else return getCheckinDate();
	}

}